<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <style>
    body{
      padding: 5px;
    }
    iframe {
      float: left;
    }
  </style>
  <body>
	<!-- 大底 -->
    <div style="width:100%;height:100%">
	  <!-- 普通组件 -->
      <div style="width: 500px;height: 300px;position: absolute;left: 0px;top: 0px;z-index: 2;opacity: 0.7;">
        <iframe
          src="panels/panel1/index.html"
          style="width: 500px; height: 300px; overflow: hidden"
          frameborder="0"
          allowTransparency="true"
        ></iframe>
      </div>
      <div  style="width: 500px;height: 300px;position: absolute;right:0px;top: 0px;z-index: 2;opacity: 0.7;">
        <iframe
          src="panels/panel2/index.html"
          style="width: 500px; height: 300px; overflow: hidden"
          frameborder="0"
          allowTransparency="true"
        ></iframe>
      </div>
     
      <div  style="width: 500px;height: 300px;position: absolute;left:0px;bottom: 0px;z-index: 2;opacity: 0.7;">
        <iframe src="panels/panel4/index.html"  style="width: 500px;height: 300px;overflow: hidden;" frameborder="0" ></iframe>
      </div>
      <div  style="width: 500px;height: 300px;position: absolute;right:0px;bottom: 0px;z-index: 2;opacity: 0.7;">
        <iframe src="panels/panel5/index.html"  style="width: 500px;height: 300px;overflow: hidden;" frameborder="0" ></iframe>
      </div>

	  <!-- 背景组件 -->
      <div style="width: 100%;height: 100%;position: absolute;left: 0px;top: 0px;z-index: 1;">
        <iframe src="panels/panel3/index.html"  style="width: 100%;height: 100%;overflow: hidden;" frameborder="0" ></iframe>
      </div>
    </div>
    <script>
      var panelEventSubscriptions = {};
      var panelUpdateHandlers = {};
      var panelEventListings = {};

      function registerUpdateHandler(panelName, func) {
        panelUpdateHandlers[panelName] = func;
      }
      function subscribeEvent(panelName, event, func) {
        panelEventSubscriptions[panelName] =
          panelEventSubscriptions[panelName] || {};
        panelEventSubscriptions[panelName][event] =
          panelEventSubscriptions[panelName][event] || [];

        var events = panelEventSubscriptions[panelName][event];
        events.push(func);
      }

      //触发更新
      function update(panelName, data) {
        var func = panelUpdateHandlers[panelName] || function () {};
        if (typeof func == "function") func(data);
      }
      //向后台推送数据
      function post(panelName, data) {
        console.log(panelName, data);
      }

      function trigger(panelName, event, data) {
        if (!panelEventSubscriptions[panelName]) return;
        if (!panelEventSubscriptions[panelName][event]) return;
        var events = panelEventSubscriptions[panelName][event];
        for (let i = 0; i < events.length; i++) {
          let func = events[i];
          if (typeof func == "function") func(data);
        }
      }

      function initPanel(options) {
        if (!options.name) {
          console.error("name is null");
          return;
        }
        var panelObj = {
          options: options,
          //事件推送
          trigger(evnetName, data) {
            trigger(options.name, evnetName, data);
          },
          //后台推送
          post(data) {
            post(options.name, data);
          },
        };

        if (options.update) {
          registerUpdateHandler(options.name, (data) =>
            options.update.call(panelObj, data)
          );
        }
        if (options.subscriptions) {
          var panelKeys = Object.keys(options.subscriptions);
          for (var i = 0; i < panelKeys.length; i++) {
            var panelKey = panelKeys[i];
            var panel = options.subscriptions[panelKey];
            var eventKeys = Object.keys(panel);
            for (var j = 0; j < eventKeys.length; j++) {
              var eventKey = eventKeys[j];
              subscribeEvent(panelKey, eventKey, (data) =>
                panel[eventKey].call(panelObj, data)
              );
            }
          }
        }

        if (options.eventDescriptions) {
          panelEventListings[options.name] = options.eventDescriptions;
        }

        return panelObj;
      }
      //显示面板 事件描述（事件清单）
      function showpPnelEventDescriptions() {
        console.log("eventDescriptions");
        console.log(panelEventListings);
      }

      setInterval(() => {
        update("panel1", { msg: "msg from root", now: new Date() });
        update("panel2", { msg: "msg from root", now: new Date() });
      }, 3000);

      setInterval(() => {
        update("panel3", { msg: "msg from root", now: new Date() });
      }, 300);
    </script>
  </body>
</html>
